#include "protreewidget.h"
#include "protreeitem.h"
#include "const.h"
#include <QDir>
#include <QHeaderView>
#include <QGuiApplication>
#include <QMenu>
#include <QFileDialog>
#include <QDebug>
#include "removeprodialog.h"
#include "opentreethread.h"
#include "slideshowdialog.h"

ProTreeWidget::ProTreeWidget(QWidget *parent)
    :QTreeWidget(parent)
    ,_right_btn_item(nullptr)
    ,_active_item(nullptr)
    ,_selected_item(nullptr)
    ,_dialog_progress(nullptr)
{
    this->header()->hide();
    connect(this,&ProTreeWidget::itemPressed,this,&ProTreeWidget::SlotItemPressed);
    //itemPressed 信号是 QTreeWidget 中的一个标准信号，用来在用户点击（按下）树形控件中的某一项时发出通知。
    _action_import = new QAction(QIcon(":/icon/import.png"),tr("导入文件"),this);
    _action_setstart = new QAction(QIcon(":/icon/core.png"),tr("设置活动项目"),this);
    _action_closepro = new QAction(QIcon(":/icon/close.png"),tr("关闭项目"),this);
    _action_slideshow = new QAction(QIcon(":/icon/slideshow.png"),tr("轮播图播放"),this);
    connect(_action_import,&QAction::triggered,this,&ProTreeWidget::SlotImport);//负责导入逻辑
    connect(_action_setstart,&QAction::triggered,this,&ProTreeWidget::SlotSetActive);//负责设置轰动项目逻辑
    connect(_action_closepro,&QAction::triggered,this,&ProTreeWidget::SlotClosePro);//负责关闭项目逻辑
    //设置双击时候的逻辑(双击左侧的item,右侧显示出对应的图片)
    connect(this,&ProTreeWidget::itemDoubleClicked,this,&ProTreeWidget::SlotDoubleClickedItem);
    //设置轮播图的逻辑
    connect(_action_slideshow,&QAction::triggered,this,&ProTreeWidget::SlotSlideShow);

    _player = new QMediaPlayer(this);
    _playlist = new QMediaPlaylist(this);
    _player->setPlaybackRate(QMediaPlaylist::Loop);//设置播放模式为循环模式
    _player->setPlaylist(_playlist);//设置播放列表
}

void ProTreeWidget::AddProToTree(const QString name, const QString path)
{
    QDir dir(path);
    QString file_path=dir.absoluteFilePath(name);
    if(_set_path.find(file_path)!=_set_path.end())
    {
        return;
    }
    QDir pro_dir(file_path);
    if(!pro_dir.exists())
    {
        bool enable = pro_dir.mkpath(file_path);
        if(!enable)
        {
            return;
        }
    }
    _set_path.insert(file_path);
    auto * item = new ProTreeItem(this,name,file_path,TreeItemPro);
    //QTreeWidgetItem::setData() 函数在 QTreeWidgetItem 中用于设置树形项（树节点）的数据。QTreeWidgetItem
    //是 Qt 中用于显示树形结构的一个类，它代表树中的一个项（节点）。每个树项可以关联多个数据字段，
    //setData() 就是用来设置这些数据字段的函数
    item->setData(0,Qt::DisplayRole,name);
    item->setData(0,Qt::DecorationRole,QIcon(":/icon/dir.png"));
    item->setData(0,Qt::ToolTipRole,file_path);
    this->addTopLevelItem(item);
}

void ProTreeWidget::SlotItemPressed(QTreeWidgetItem *pressedItem, int column)
{
    if(QGuiApplication::mouseButtons() == Qt::RightButton)
    {
        QMenu menu(this);
        int itemtype = pressedItem->type();
        if(itemtype == TreeItemPro)
        {
            _right_btn_item = pressedItem;
            menu.addAction(_action_import);
            menu.addAction(_action_setstart);
            menu.addAction(_action_closepro);
            menu.addAction(_action_slideshow);
            menu.exec(QCursor::pos());//设置弹出位置为鼠标右键的位置
        }
    }
}

void ProTreeWidget::SlotImport()//负责导入
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::Directory);
    file_dialog.setWindowTitle(tr("选择导入的文件夹"));
    QString path;
    if(!_right_btn_item){
        qDebug()<<"_right_btn_item";
        return;
    }
    path = dynamic_cast<ProTreeItem*>(_right_btn_item)->GetPath();
    file_dialog.setDirectory(path);
    file_dialog.setViewMode(QFileDialog::Detail);
    QStringList fileNames;
    if(file_dialog.exec())
    {
        fileNames = file_dialog.selectedFiles();
    }
    if(fileNames.length()==0)
    {
        return;
    }

    QString import_path = fileNames.at(0);
    int file_count = 0;
    _dialog_progress = new QProgressDialog(this);

    _thread_create_pro = std::make_shared<ProTreeThread>(std::ref(import_path),std::ref(path),_right_btn_item,
                                                         file_count,this,_right_btn_item,nullptr);
    connect(_thread_create_pro.get(),&ProTreeThread::SigUpdateProgress,this,&ProTreeWidget::SlotUpdateProgress);
    connect(_thread_create_pro.get(),&ProTreeThread::SigFinishProgress,this,&ProTreeWidget::SlotFinishProgress);
    connect(_dialog_progress,&QProgressDialog::canceled,this,&ProTreeWidget::SlotCancelProgress);
    connect(this,&ProTreeWidget::SigCancelProgress,_thread_create_pro.get(),&ProTreeThread::SlotCancelProgress);
    _thread_create_pro->start();

    _dialog_progress->setWindowTitle("Please wait...");
    _dialog_progress->setFixedWidth(PROGRESS_WIDTH);
    _dialog_progress->setRange(0,PROGRESS_WIDTH);
    _dialog_progress->exec();
}

void ProTreeWidget::SlotSetActive()//设置激活项目
{
    //将原来的激活项设置为不加粗的字体，然后将现在点击的项目设置为加粗字体
    if(!_right_btn_item){
        return;
    }
    QFont nullFont;
    nullFont.setBold(false);
    if(_active_item){
        _active_item->setFont(0,nullFont);
    }
    _active_item = _right_btn_item;
    nullFont.setBold(true);
    _active_item->setFont(0,nullFont);
}

void ProTreeWidget::SlotClosePro()
{
    RemoveProDialog remove_pro_dialog;
    auto res = remove_pro_dialog.exec();
    if(res != QDialog::Accepted){
        return;
    }
    bool b_remove = remove_pro_dialog.IsRemoved();//检查是否需要将文件从磁盘中移除
    auto index_right_btn = this->indexOfTopLevelItem(_right_btn_item);//返回给定顶级项的索引，如果找不到该项，则返回-1
    auto* protreeitem = dynamic_cast<ProTreeItem*>(_right_btn_item);
    auto * selecteditem = dynamic_cast<ProTreeItem*>(_selected_item);
    auto delete_path = protreeitem->GetPath();
    _set_path.remove(delete_path);//从集合中移除
    if(b_remove){
        QDir delete_dir(delete_path);
        delete_dir.removeRecursively();
    }
    if(protreeitem == _active_item){
        _active_item = nullptr;
    }

    if(selecteditem && protreeitem == selecteditem->GetRoot()){
        selecteditem = nullptr;
        _selected_item = nullptr;
        emit SigClearSelected();
    }

    delete this->takeTopLevelItem(index_right_btn);//从目录树中移除
    _right_btn_item = nullptr;
}

void ProTreeWidget::SlotUpdateProgress(int count)
{
    if(!_dialog_progress){
        return;
    }
    if(count >= PROGRESS_MAX){
        _dialog_progress->setValue(count%PROGRESS_MAX);
    }else{
        _dialog_progress->setValue(count);
    }
}

void ProTreeWidget::SlotFinishProgress()
{
    _dialog_progress->setValue(PROGRESS_MAX);
    _dialog_progress->deleteLater();
}

void ProTreeWidget::SlotCancelProgress()
{
    emit SigCancelProgress();
    delete _dialog_progress;
    _dialog_progress = nullptr;
}

void ProTreeWidget::SlotUpOpenProgress(int count)
{
    if(!_open_progressdlg){
        return;
    }
    if(count >= PROGRESS_MAX){
        _open_progressdlg->setValue(count%PROGRESS_MAX);
    }else{
        _open_progressdlg->setValue(count);
    }
}

void ProTreeWidget::SlotFinishOpenProgress()
{
    if(!_open_progressdlg){
        return;
    }
    _open_progressdlg->setValue(PROGRESS_MAX);
    delete _open_progressdlg;
    _open_progressdlg = nullptr;
}

void ProTreeWidget::SlotCancelOpenProgress()
{
    emit SigCancelOpenProgress();
    delete _open_progressdlg;
    _open_progressdlg = nullptr;
}

void ProTreeWidget::SlotDoubleClickedItem(QTreeWidgetItem *item, int column)
{
    if(QGuiApplication::mouseButtons() == Qt::LeftButton){
        auto * tree_doubleItem = dynamic_cast<ProTreeItem*>(item);
        if(!tree_doubleItem){
            return;
        }
        int itemtype = tree_doubleItem->type();
        if(itemtype == TreeItemPic){
            emit SigUpdateSelected(tree_doubleItem->GetPath());
            _selected_item = item;//缓存当前选中的条目
        }
    }
}

void ProTreeWidget::SlotSlideShow()
{
    if(!_right_btn_item){
        return;
    }
    auto * right_pro_item = dynamic_cast<ProTreeItem*>(_right_btn_item);
    auto * last_child_item = right_pro_item->GetLastPicChild();
    if(!last_child_item){
        return;
    }
    auto * first_child_item = right_pro_item->GetFirstPicChild();
    if(!first_child_item){
        return;
    }
    qDebug()<<"ProTreeWidget::SlotSlideShow:"<<right_pro_item->GetPath();
    _slide_show_dlg = std::make_shared<SlideShowDialog>(this,first_child_item,last_child_item);
    _slide_show_dlg->setModal(true);
    _slide_show_dlg->showMaximized();
}

void ProTreeWidget::SlotOpenPro(const QString &path)//添加
{
    if(_set_path.find(path) != _set_path.end()){
        return;
    }
    _set_path.insert(path);
    int file_count = 0;
    QDir pro_dir(path);
    QString proname = pro_dir.dirName();
    _thread_open_pro = std::make_shared<OpenTreeThread>(path,file_count,this,nullptr);
    _open_progressdlg = new QProgressDialog(this);
    //连接更新进度框操作
    connect(_thread_open_pro.get(),&OpenTreeThread::SigUpdateProgress,this,&ProTreeWidget::SlotUpOpenProgress);
    connect(_thread_open_pro.get(),&OpenTreeThread::SigFinishProgress,this,&ProTreeWidget::SlotFinishOpenProgress);
    connect(_open_progressdlg,&QProgressDialog::canceled,this,&ProTreeWidget::SlotCancelProgress);
    connect(this,&ProTreeWidget::SigCancelOpenProgress,_thread_open_pro.get(),&OpenTreeThread::SlotCancelProgress);
    _thread_open_pro->start();
    _open_progressdlg->setWindowTitle("Please wait...");
    _open_progressdlg->setFixedWidth(PROGRESS_WIDTH);
    _open_progressdlg->setRange(0,PROGRESS_WIDTH);
    _open_progressdlg->exec();
}

void ProTreeWidget::SlotPreShow()
{
    if(!_selected_item){
        return;
    }
    auto* curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetPreItem();
    if(!curItem){
        return;
    }
    emit SigUpdatePic(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotNextShow()
{
    if(!_selected_item){
        return;
    }
    auto* curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetNextItem();
    if(!curItem){
        return;
    }
    emit SigUpdatePic(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotSetMusic()
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::ExistingFiles);
    file_dialog.setWindowTitle(tr("选择音频文件"));
    file_dialog.setDirectory(QDir::currentPath());
    file_dialog.setViewMode(QFileDialog::Detail);
    file_dialog.setNameFilter("(*.mp3)");
    QStringList fileNames;
    if(file_dialog.exec()){
        fileNames = file_dialog.selectedFiles();
    }else{
        return;
    }
    if(fileNames.length() <= 0){
        return;
    }
    _playlist->clear();
    for(auto filename:fileNames){
        qDebug() << "filename is " << filename << endl;
        _playlist->addMedia(QUrl::fromLocalFile(filename));
        //每个文件路径转换为 QUrl 对象，然后添加到 _playlist 中。QUrl::fromLocalFile(filename)
        //将本地文件路径 filename 转换为 QUrl 格式，addMedia() 方法则将这些文件添加到播放列表中。
    }
    if(_player->state() != QMediaPlayer::PlayingState){
        _playlist->setCurrentIndex(0);
        //首先检查 _player（一个 QMediaPlayer 对象）的当前播放状态。如果播放器当前没有在播放状态下（即不是 QMediaPlayer::PlayingState），
        //则调用 setCurrentIndex(0) 设置播放列表从第一个媒体文件开始播放。
        //setCurrentIndex(0) 方法将播放列表的当前索引设置为 0，即第一个媒体文件。
    }
}

void ProTreeWidget::SlotStartMusic()
{
    _player->play();
}

void ProTreeWidget::SlotStopMusic()
{
    _player->stop();
}
